package com.frame.work.frame.deal.device0fad;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.frame.work.common.exception.ErrorType;
import com.frame.work.common.exception.ZyServerException;
import com.frame.work.common.util.CmdUtils;
import com.frame.work.common.util.JsonToMqtt;
import com.frame.work.config.SpringUtil;
import com.frame.work.frame.deal.base.BaseFrame;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author wjming
 * @ClassName: AcController0Fad0702
 * @Description: 空调控制器数据帧解析器
 * @Date 2021-08-03 9:57
 */
@Data
public class AcController0Fad0702Main extends BaseFrame {
    /**
     * zigbee设备的开关状态
     */
    private String switchState;
    private String spreadingType;

    public AcController0Fad0702Main(String gatewayMac, String data) {
        super(gatewayMac, data);
        RabbitTemplate rabbitTemplate = SpringUtil.getBean(RabbitTemplate.class);
        final String acGatewayUpdate = "acGatewayUpdate";
        final String acUpdate = "acUpdate";
        //控制器数据长度
        String controllerLength = "25";
        //空调数据长度
        String acLength = "27";
        this.switchState = "01";
        this.spreadingType = Device0Fad0702Action.getSpreadingType(data);

        if (acLength.equals(CmdUtils.getDateLength(data))) {
            AcStatusAction acStatusAction = new AcStatusAction(data);
            this.setActions(acStatusAction);
            JsonToMqtt.sendBaseMQTT(gatewayMac, JSONObject.toJSONString(this));
            Map<String, Object> stringObjectMap = JSON.parseObject(JSON.toJSONString(this), new TypeReference<Map<String, Object>>() {
            });
            stringObjectMap.put("type", acUpdate);
            rabbitTemplate.convertAndSend("smarthome.ac.center.channel", stringObjectMap);
        }

        if (controllerLength.equals(CmdUtils.getDateLength(data))) {
            Device0Fad0702Action device0Fad0702Action = new Device0Fad0702Action(data);
            this.setActions(device0Fad0702Action);
            JsonToMqtt.sendMQTT(gatewayMac, JSONObject.toJSONString(this));
            Map<String, Object> stringObjectMap = JSON.parseObject(JSON.toJSONString(this), new TypeReference<Map<String, Object>>() {
            });
            stringObjectMap.put("type", acGatewayUpdate);
            rabbitTemplate.convertAndSend("smarthome.ac.center.channel", stringObjectMap);
        }


        return;

    }
}


/**
 * 控制器上报空调时候的Action信息
 */
@Data
final class AcStatusAction {
    private String acAddress;
    /**
     * 开关状态
     */
    private String switchState;
    /**
     * 空调模式
     */
    private String mode;
    /**
     * 风速
     */
    private String speed;
    /**
     * 温度
     */
    private String setTemperature;
    /**
     * 室内温度
     */
    private String indoorTemperature;
    /**
     * 错误码 00无故障
     */
    private String errorCode;

    public AcStatusAction(final String data) {
        this.acAddress = getAcAddress(data);
        this.switchState = getSwitchState(data);
        this.mode = getMode(data);
        this.speed = getSpeed(data);
        this.setTemperature = getSetTemperature(data);
        this.indoorTemperature = getIndoorTemperature(data);
        this.errorCode = errorCode(data);
    }

    /**
     * 获取空调具体地址
     *
     * @param data
     * @return
     */
    private static String getAcAddress(final String data) {
        String out = StringUtils.substring(data, 58, 60);
        String inside = StringUtils.substring(data, 60, 62);
        int i = Integer.parseInt(out);
        return i + "_" + inside;
    }

    /**
     * @param data
     * @return
     */
    private static String getSwitchState(final String data) {
        return StringUtils.substring(data, 62, 64);
    }

    /**
     * 获取空调设定温度
     *
     * @param data
     * @return
     */
    private static String getSetTemperature(final String data) {
        String substring = StringUtils.substring(data, 64, 66);
        return Integer.parseInt(substring, 16) + "";
    }

    /**
     * @param data
     * @return
     */
    private static String getMode(final String data) {
        return StringUtils.substring(data, 66, 68);
    }

    /**
     * 获取风速
     *
     * @param data
     * @return
     */
    private static String getSpeed(final String data) {
        return StringUtils.substring(data, 68, 70);
    }

    private static String getIndoorTemperature(final String data) {
        String substring = StringUtils.substring(data, 70, 72);
        return Integer.parseInt(substring, 16) + "";
    }

    private static String errorCode(final String data) {
        return StringUtils.substring(data, 72, 74);
    }
}

/**
 * 智能空调控制器上报Action
 */
@Data
class Device0Fad0702Action {
    /**
     * 通用绑定标志02表示可以被绑定
     */
    private String spreadingType;
    /**
     * 空调列表
     */
    private List<String> acAddressList;

    /**
     * @param data
     */
    public Device0Fad0702Action(final String data) {
        this.spreadingType = Device0Fad0702Action.getSpreadingType(data);
        this.acAddressList = Device0Fad0702Action.getAcList(data);
    }

    /**
     * 获取通用绑定标识符号
     *
     * @param data
     * @return
     */
    public static String getSpreadingType(final String data) {
        return StringUtils.substring(data, 38, 40);
    }

    /**
     * 获取空调列表
     *
     * @param data
     * @return
     */
    private static List<String> getAcList(final String data) {
        final String ignoreData = "FFFFFFFFFFFFFFFF";
        List<String> getAddressList = new ArrayList<>(16);
        String acStringHex16 = StringUtils.substring(data, 58, 74);
        if (ignoreData.equalsIgnoreCase(acStringHex16)) {
            throw new ZyServerException(ErrorType.INVALID_PARAMS.getCode(), "数据忽略");
        }

        byte[] bytes = CmdUtils.hexStr2Byte(acStringHex16);

        for (int i = 0; i < bytes.length; i++) {
            List<String> list = CmdUtils.byteToBit(bytes[i], i);
            getAddressList.addAll(list);
        }
        return getAddressList;
    }

}

